import React, { FC, useEffect, useCallback } from 'react';
import { Spin } from 'antd';
import { isEmpty, isArray, isFunction } from 'lodash';
import { observer } from 'mobx-react';

import Table from '@components/Table';
import Button from '@components/Button';
import CollapseQueryBar from '@components/CollapseQueryBar';
import { useForm } from '@components/Form';
import EditDrawerForm from '@components/EditDrawerForm';

import { useResetFormOnCloseModal } from '@utils/renderer';

import type { RbProTableProps } from './RbProTableProps';
import OperationBar from './OperationBar';
import RbProTableStore from './stores';

/** RbProTable表格作用域 */
export { RbProTableStore };

/** props未传入store时自动创建使用 */
const _store = new RbProTableStore();

const RbProTable: FC<RbProTableProps> = ({
  rowKey,
  headerTitle,
  loading = false,
  refreshRandom,
  selectionType,
  toolBarRender,
  actionUrl = '',
  paging = true,
  columns = [],
  editFormItems = [],
  beforeOpenModalQuery,
  queryConfig = {},
  addConfig = {},
  updateConfig = {},
  deleteConfig = {},
  store = _store,
  ...rest
}) => {
  const {
    queryFromItems = [],
    queryInitialValues = {},
    queryFormat,
    queryUrl = actionUrl,
    queryMethod = 'GET'
  } = queryConfig;

  const {
    addModalTitle = '新增',
    addFormItems = editFormItems,
    addInitialValues = {},
    addUrl = actionUrl,
    addMethod = 'POST'
  } = addConfig;

  const {
    updateModalTitle = '编辑',
    updateFormItems = editFormItems,
    updateUrl = actionUrl,
    updateMethod = 'PUT'
  } = updateConfig;

  const {
    deleteTip = '是否确定删除?',
    deleteUrl = actionUrl,
    deleteMethod = 'DELETE'
  } = deleteConfig;

  const [queryForm] = useForm(); // 查询表单
  const [editForm] = useForm(); // 编辑表单

  useEffect(() => {
    store.initStore({
      queryUrl,
      queryMethod,
      queryFormat,
      addUrl,
      addMethod,
      updateUrl,
      updateMethod,
      deleteUrl,
      deleteMethod,
      paging,
      selectionType,
      columns,
      queryForm,
      editForm,
      deleteTip
    });
    store.query(queryInitialValues);
  }, [
    refreshRandom,
    columns,
    queryUrl,
    queryMethod,
    paging,
    selectionType,
    addUrl,
    addMethod,
    updateUrl,
    updateMethod,
    deleteTip,
    deleteUrl,
    deleteMethod
  ]);

  useResetFormOnCloseModal({ form: editForm, openFlag: store.openFlag });

  /** 打开 新增 | 编辑  抽屉 */
  const handleOpenEditDrawer = useCallback(
    async (type: string) => {
      store.setOperationType(type);

      if (isFunction(beforeOpenModalQuery)) await beforeOpenModalQuery();

      if (type === 'update') {
        // 设置抽屉表单数据
        editForm.setFieldsValue(store?.selected[0] || {});
      }

      store.setOpenFlag(true);
    },
    [editForm, beforeOpenModalQuery]
  );

  /** 获取内置功能条(按钮) */
  const getBuiltInToolBar = useCallback(
    (toolBars: any[]) => {
      const finToolBars: any[] = [];
      toolBars.forEach((barItem: any) => {
        switch (barItem) {
          case 'add':
            if (addUrl && !isEmpty(addFormItems))
              finToolBars.push(
                <Button key="add" type="primary" onClick={() => handleOpenEditDrawer('create')}>
                  新增
                </Button>
              );
            break;
          case 'update':
            if (updateUrl && !isEmpty(updateFormItems))
              finToolBars.push(
                <Button
                  key="update"
                  type="primary"
                  disabled={store.selected.length !== 1}
                  onClick={() => handleOpenEditDrawer('update')}
                >
                  修改
                </Button>
              );
            break;
          case 'delete':
            if (deleteUrl)
              finToolBars.push(
                <Button
                  key="delete"
                  type="primary"
                  danger
                  disabled={!store.selectedKeys.length}
                  onClick={() => store.handleDelete()}
                >
                  删除
                </Button>
              );
            break;
          default:
            finToolBars.push(barItem);
            break;
        }
      });
      return finToolBars;
    },
    [addFormItems, addUrl, deleteUrl, handleOpenEditDrawer, updateFormItems, updateUrl]
  );

  /** 勾选配置 */
  let rowSelection: any;
  if (selectionType) {
    rowSelection = {
      type: selectionType,
      selectedRowKeys: store.selectedKeys,
      onChange: (newSelectedRowKeys: React.Key[], newSelectedRows: any[]) => {
        store.setSelectedKeys(newSelectedRowKeys);
        store.setSelected(newSelectedRows);
      }
    };
  }

  /** 操作区处理 */
  let toolBar: any = toolBarRender;
  if (toolBarRender && typeof toolBarRender === 'function') {
    toolBar = toolBarRender();
  }
  if (isArray(toolBar)) {
    toolBar = getBuiltInToolBar(toolBar);
  }

  return (
    <Spin spinning={store.loading || loading}>
      {queryFromItems && (
        <CollapseQueryBar
          form={queryForm}
          queryFromItems={queryFromItems}
          initialValues={queryInitialValues}
          handleSearch={(params: any) => store.query(params)}
          queryFormat={queryFormat}
        />
      )}
      {(headerTitle || toolBarRender) && (
        <OperationBar headerTitle={headerTitle} toolBar={toolBar} columns={columns} store={store} />
      )}
      <Table
        rowKey={rowKey}
        columns={store.columns}
        dataSource={store.tableData}
        rowSelection={!store.columns.length ? false : rowSelection}
        pagination={paging ? store.pagination : false}
        onChange={(pagination: any, filters: any, sorter: any) =>
          paging ? store.handleTableChange(pagination, filters, sorter) : undefined
        }
        {...rest}
      />
      {store.openFlag && (
        <EditDrawerForm
          title={store.operationType === 'update' ? updateModalTitle : addModalTitle}
          initialValues={addInitialValues}
          form={editForm}
          loading={store.saveLoading}
          openFlag={store.openFlag}
          setOpenFlag={(flag: boolean) => store.setOpenFlag(flag)}
          handleSave={() => store.handleSave()}
          formItems={store.operationType === 'update' ? updateFormItems : addFormItems}
        />
      )}
    </Spin>
  );
};

export default observer(RbProTable);
